package dyyx;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import com.google.common.base.CharMatcher;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.Collections2;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Multiset;
import com.google.common.collect.Table;
import com.google.common.primitives.Ints;

public class Hello {

	// on char or string
	private static final Joiner joiner = Joiner.on(",").skipNulls();

	private static final Splitter splitter = Splitter.on(",").trimResults().omitEmptyStrings();

	public static void main(String[] args) throws Exception {
		System.out.println("hello,guava," + new Date());
		//
		String str = joiner.join(Lists.newArrayList("a", null, "b", "", "c"));
		// a,b,,c
		System.out.println(str);

		str = "  a,,b, ,c,,,    ";
		List<String> list = splitter.splitToList(str);
		System.out.println(list.size());

		str = joiner.join(list);
		// a,b,c
		System.out.println(str);
		// only the digits
		System.out.println(CharMatcher.javaDigit().retainFrom("dyyx007"));
		// trim whitespace at ends, and replace/collapse whitespace into single spaces
		System.out.println(CharMatcher.whitespace().trimAndCollapseFrom("   hello  dyyx007    ", ' '));
		// star out all digits
		System.out.println(CharMatcher.javaDigit().replaceFrom("dyyx007", "*"));
		// eliminate all characters that aren't digits or lowercase
		System.out.println(CharMatcher.javaDigit().or(CharMatcher.javaLowerCase()).retainFrom("HELLO,dyyx007"));

		// Ints
		List<Integer> intList = Ints.asList(1,2,3);
		System.out.println(joiner.join(intList));
		System.out.println(Ints.join(",",1,2,3));
        int[]intarr1 = Ints.toArray(intList);
        int[]intarr2 = new int[]{2,3,4};
        int[]intarr3 = Ints.concat(intarr1,intarr2);
		System.out.println(joiner.join(Ints.asList(intarr3)));
		System.out.println(Ints.min(intarr1)+","+Ints.max(intarr2));
		
		System.out.println(Ints.contains(intarr3, 3));
		System.out.println(Ints.contains(intarr3, 9));
		
		// Multiset
		Multiset<String> mset =  HashMultiset.create();
		mset.add("a");
		mset.add("b");
		mset.add("c");
		mset.add("a");
		// [a x 2, b, c]
		System.out.println(mset);
		System.out.println(mset.count("a"));
		System.out.println(mset.count("b"));


		// 
		list = new ArrayList<String>();
		list.add("a");
		list.add("b");
		List<String> readOnlyList = Collections.unmodifiableList(list);
		try{
		    readOnlyList.add("c");
		}catch(Exception e){
			// java.lang.UnsupportedOperationException
			System.out.println(e);
		}
		list.add("c");
		System.out.println(readOnlyList.size());

		// Defensive Copies，保护性拷贝 
		readOnlyList = Collections.unmodifiableList(new ArrayList<String>(list));
		list.add("d");
		System.out.println(readOnlyList.size());

        List<String> immutableList1 = ImmutableList.of("a","b");
        List<String> immutableList2 = ImmutableList.copyOf(list);
        
        list.add("e");
        System.out.println(list.size()+","+immutableList2.size());
        
        // Multimap
        Multimap<String,String> multimap = ArrayListMultimap.create();
        multimap.put("pet", "cat");
        multimap.put("pet", "dog");
        Collection<String> pets =multimap.get("pet");
        System.out.println(joiner.join(pets));
        
        // BiMap
        BiMap<String,String> bimap = HashBiMap.create();
        bimap.put("dugang", "dyyx007");
        bimap.put("dugang", "dyyx");
        System.out.println(bimap.get("dugang"));
        System.out.println(bimap.inverse().get("dyyx007"));
        System.out.println(bimap.inverse().get("dyyx"));

        // table 
        // name course score
        
        Table<String,String,Integer> table = HashBasedTable.create();
        table.put("cat", "math", 80);
        table.put("cat", "compute", 85);
        table.put("dog", "math", 60);
        table.put("dog", "compute", 90);
        
        Set<Table.Cell<String,String,Integer>> cells = table.cellSet();
        for(Table.Cell<String,String,Integer> cell:cells){
        	System.out.println(cell.getRowKey()+","+cell.getColumnKey()+","+cell.getValue());
        }
        Set<String> rowKeys = table.rowKeySet();
        System.out.println(rowKeys);
        
        Set<String> columnKeys = table.columnKeySet();
        System.out.println(columnKeys);    
        System.out.println(table.row("cat"));
        System.out.println(table.column("math"));
        
        // 
        List<Integer> intlist = Ints.asList(1,2,3,4,5);
        // sublist 大小2
        List<List<Integer>> intlists = Lists.partition(intlist, 2);
        for(List<Integer> item:intlists){
        	System.out.println(item);
        }
        
        
        System.out.println(Objects.hash(1,2,3));
        System.out.println(Objects.hash("a"));
        System.out.println(Objects.hash("a","b"));


        List<String> strlist = Lists.newArrayList("1", "2", "3");
        // string to integer
        List<Integer> intlist2 = Lists.transform(strlist, new Function<String, Integer>() {
                   @Override
                   public Integer apply(String s) {
                       return Integer.valueOf(s);
                   }
               });

        System.out.println(intlist2);
        

        // java8
        intlist2 = strlist.stream().map(Integer::valueOf).collect(Collectors.toList());
        System.out.println(intlist2);
        
        strlist = Lists.newArrayList("hello", "world", "haha");
        //  find the first element  startsWith 'h' 
        str = Iterables.find(strlist, new Predicate<String>() {
            @Override
            public boolean apply(String input) {
                return input.startsWith("h");
            }
        });

        System.out.println(str);
        
        // java8
        str = strlist.stream().findFirst().filter(input -> input.startsWith("h")).get();
        System.out.println(str);

        List<String> strlist2 = Lists.newArrayList(Collections2.filter(strlist, new Predicate<String>() {
            @Override
            public boolean apply(String s) {
                return s.startsWith("h");
            }
        }));

        System.out.println(strlist2);
        
        // java8
        strlist2 = strlist.stream().filter(input -> input.startsWith("h")).collect(Collectors.toList());
        System.out.println(strlist2);

		
		//
        List<Apple> appleList = Lists.newArrayList(new Apple(1, "red"), new Apple(2, "red"), new Apple(3, "green"), new Apple(4, "green"));
        Map<Integer, Apple> appleMap = Maps.uniqueIndex(appleList, new Function<Apple, Integer>() {
            @Override
            public Integer apply(Apple apple) {
                return apple.getId();
            }
        });

        System.out.println(appleMap);
        
        //  group by color Map<color，Collection<Apple>>
        Multimap<String, Apple> multiAppleMap = Multimaps.index(appleList,
                   new Function<Apple, String>() {
                       @Override
                       public String apply(Apple apple) {
                           return apple.getColor();
                       }
                   });
        System.out.println(multiAppleMap);
        
        // java8
        Map<Integer, Apple> appleMap2 = appleList.stream().collect(Collectors.toMap(Apple::getId, apple -> apple));
        System.out.println(appleMap2);

        Map<String, List<Apple>> appleMap3 = appleList.stream().collect(Collectors.groupingBy(Apple::getColor));
        System.out.println(appleMap3);

        


		


        
		
		
	}

}
